<template>
  <el-input class="ju-day-select"
            :clearable="clearable"
            :disabled="disabled"
            placeholder="请选择日子"
            :value="dayText"
            @clear="() => multiple ? $emit('change',[]) : $emit('change',null)">
    <template #append>
      <el-popover :disabled="disabled"
                  placement="top"
                  popper-class="p-0"
                  trigger="click">
        <el-button slot="reference">
          <ju-icon icon="calendar-day"
                   svg-icon></ju-icon>
        </el-button>
        <div class="day-items p-2">
          <div v-for="item in options"
               :key="`day-item-${item}`"
               class="d-inline-flex align-items-center justify-content-center position-relative border-box day-item"
               :class="{'is-checked':multiple ? value.some(s => s === item.value) : value === item.value}"
               @click.stop="doSelect(item.value)">
            {{ item.text }}
            <ju-icon v-if="multiple ? value.some(s => s === item.value) : value === item.value"
                     class="checked-icon"
                     icon="check"
                     svg-icon></ju-icon>
          </div>
          <div class="d-inline-flex align-items-center justify-content-center position-relative border-box day-item day-item-last "
               :class="{'is-checked':multiple ? value.some(s => s === -1) && !isAllChecked : value === -1}"
               @click.stop="isAllChecked || doSelect(-1)">
            最后一天
            <ju-icon v-if="multiple ? value.some(s => s === -1) && !isAllChecked : value === -1"
                     class="checked-icon"
                     icon="check"
                     svg-icon></ju-icon>
          </div>
          <div v-if="multiple"
               class="d-inline-flex align-items-center justify-content-center position-relative border-box day-item day-item-all "
               @click.stop="doToggleSelectAll">
            {{ isAllChecked ? "取消全选" : "全选" }}
          </div>
        </div>
      </el-popover>
    </template>
  </el-input>
</template>

<script lang="ts">
  import { Component, Model, Vue, Prop } from "@some21/vue-class-decorator";
  import { sortBy } from "lodash";

  const DAY_OPTIONS = [];
  for (let index = 1; index <= 31; index++) {
    DAY_OPTIONS.push({ text: index, value: index });
  }

  @Component({
    name: "ju-day-select",
  })
  export default class extends Vue {
    @Model("change", { type: [Array, Number] })
    value;
    @Prop({ type: Boolean, default: false })
    multiple: boolean;
    @Prop({ type: Boolean, default: false })
    disabled: boolean;
    @Prop({ type: Boolean, default: false })
    clearable: boolean;

    options = DAY_OPTIONS;
    get dayText() {
      if (this.multiple) {
        if (this.value && this.value.length) {
          const texts = [];

          const monthDays = sortBy(
            DAY_OPTIONS.filter(f => this.value.some(s => s === f.value && f.value !== -1)),
            "value"
          );
          if (monthDays.length) {
            let startDay;
            let endDay;
            monthDays.forEach(item => {
              // 判断记录的开始日是否存在值，若不存在，则进行赋值操作
              if (!startDay) {
                startDay = item.value;
                endDay = item.value;
              } else {
                if (item.value - endDay === 1) {
                  endDay = item.value;
                } else {
                  if (endDay - startDay > 1) {
                    texts.push(`${startDay}-${endDay}`);
                  } else if (startDay === endDay) {
                    texts.push(startDay);
                  } else {
                    texts.push(startDay);
                    texts.push(endDay);
                  }
                  startDay = item.value;
                  endDay = item.value;
                }
              }
            });

            if (endDay - startDay > 1) {
              texts.push(`${startDay}-${endDay}`);
            } else if (startDay === endDay) {
              texts.push(startDay);
            } else {
              texts.push(startDay);
              texts.push(endDay);
            }
          }

          if (!this.isAllChecked && this.value.some(s => s === -1)) {
            texts.push("最后一天");
          }
          return texts.join(", ");
        } else {
          return "";
        }
      } else {
        if (this.value === -1) {
          return "最后一天";
        } else {
          return this.value;
        }
      }
    }
    get isAllChecked() {
      if (this.multiple) {
        return this.options.every(e => this.value.some(s => s === e.value));
      }
    }
    doToggleSelectAll() {
      if (this.isAllChecked) {
        // 当存在选中【最后一天】的时候，清空全选时，保留【最后一天】
        if (this.value.some(s => s === -1)) {
          this.$emit("change", [-1]);
        } else {
          this.$emit("change", []);
        }
      } else {
        this.$emit(
          "change",
          [...this.value, ...this.options.map(m => m.value)] // 全选时会排除【最后一天】选项，此处保留最后一天的选择
        );
      }
    }
    doSelect(day) {
      if (this.multiple) {
        if (this.value) {
          const index = this.value.findIndex(f => f === day);
          if (index >= 0) {
            this.value.splice(index, 1);
          } else {
            this.value.push(day);
          }
        } else {
          this.value = [day];
        }
      } else {
        this.value = day;
      }
      this.$emit("change", this.value);
    }
  }
</script>

<style lang="scss" scoped>
  .day-items {
    width: 315px;
  }
  .day-item {
    margin: 2.5px;
    width: 40px;
    height: 40px;
    border: 1px solid var(--theme-gray-200);
    border-radius: var(--theme-radius);
    vertical-align: top;

    &:hover {
      cursor: pointer;
      border-color: var(--theme-primary);
    }
    &.is-checked {
      border-color: var(--theme-primary);
      color: var(--theme-primary);

      .checked-icon {
        position: absolute;
        right: 0;
        top: 0;
        background: var(--theme-primary);
        color: var(--theme-white);
        border-bottom-left-radius: 50%;
      }
    }

    &.day-item-last,
    &.day-item-all {
      width: 85px;
    }

    &.day-item-all {
      color: rgba(var(--theme-orange-rgb), 0.8);
      border-color: rgba(var(--theme-orange-rgb), 0.3);

      &:hover {
        color: var(--theme-orange);
        border-color: currentColor;
      }
    }
  }
</style>
